<template>
  <div>
    <!-- 19 增加全屏按钮 -->
    <!-- 20 用控制面板控制全屏
       <button class="full-screen-btn" @click="onClickFullScreen">全屏</button> 
      -->
  </div>
</template>

<script>
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
// 20 导入gui控制面板
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";

// 导入HDR加载器
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";

/**
 * 值类型
 * - Vector3
 * (x,y,z)
 * - Euler 欧拉: 描述一个旋转变换,通过指定轴顺序和其各个轴向上的指定旋转角度来旋转一个物体
 * (x,y,z,order) - order: 'XYZ' or 'YXZ' or 'ZXY' or 'ZYX',
 */

export default {
  data() {
    return {};
  },
  methods: {
    // 19 增加全屏按钮
    onClickFullScreen() {
      // 渲染器画布全屏
      window.renderer && window.renderer.domElement.requestFullscreen();
      // 浏览器窗口全屏
      // document.body.requestFullscreen()
      // 退出全屏
      // document.exitFullscreen()
    },
  },
  mounted() {
    // 1 创建场景
    const scene = new THREE.Scene();

    // 2 创建相机
    const camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000,
    );
    camera.position.z = 5;
    camera.position.x = 5;
    camera.position.y = 5;
    // 3 相机指向原点
    camera.lookAt(new THREE.Vector3(0, 0, 0));

    // 4 创建一个渲染器 canvas
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // 8 添加轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement); // 创建轨道控制器, 第二参数表示监听事件的DOM
    // const controls = new OrbitControls(camera, document.body); // 创建轨道控制器, 第二参数表示监听事件的DOM, 监听了body后, OrbitControls会拦截所有的事件
    // 9 设置阻尼
    controls.enableDamping = true;
    controls.dampingFactor = 0.1; // 设置阻尼系数, 数值越小, 惯性越大, 数值越大, 停下来越快

    // 10 自动旋转
    controls.autoRotate = false; // 自动旋转

    // 7 添加世界坐标辅助器
    const axesHelper = new THREE.AxesHelper(5); // 辅助线长度为5
    scene.add(axesHelper);

    // 6 动作绘制
    function animate() {
      /* 8 添加轨道控制器 根据控制器更新画面 */
      controls.update();
      requestAnimationFrame(animate); // 请求浏览器重新绘制画面
      /* 自动旋转
      cube.rotation.x += 0.01; // x轴旋转速度增加
      cube.rotation.y += 0.01; // y轴旋转速度增加
      */
      renderer.render(scene, camera); // 渲染场景和相机设置到屏幕上
    }
    animate(); // 开始动画循环

    // 18 监听全屏事件, 让画布适配屏幕尺寸
    window.addEventListener("resize", function() {
      // 重置渲染器宽高比
      renderer.setSize(window.innerWidth, window.innerHeight);
      // 重置相机宽高比
      camera.aspect = window.innerWidth / window.innerHeight;
      // 更新相机投影矩阵
      camera.updateProjectionMatrix();
    });
    /** 20 用GUI控制面板控制全屏
    // 19 增加全屏按钮
    window.scene = scene;
    window.camera = camera;
    window.renderer = renderer;
    window.controls = controls;
    */
    // 20 GUI控制面板
    let eventObj = {
      Fullscreen: function() {
        document.body.requestFullscreen();
      },
      ExitFullscreen: function() {
        document.exitFullscreen();
      },
    };
    const gui = new GUI();
    // 第一个参数是事件对象, 第二个参数是该事件对象的key
    gui.add(eventObj, "Fullscreen").name("全屏");
    gui.add(eventObj, "ExitFullscreen").name("退出全屏");

    // 23 创建一个纹理加载器
    const textureLoader = new THREE.TextureLoader();
    // 载入纹理
    const texture = textureLoader.load("/imgs/img_4.png");

    // 24 载入环境遮挡贴图
    // const aoMap = textureLoader.load("/imgs/img_4.png");

    // 25 载入透明度贴图
    // const alphaMap = textureLoader.load("/imgs/alphaMap.jpg");

    // 26 载入光照贴图
    // const lightMap = textureLoader.load("/imgs/lightMap1.png");

    // 27 创建RGBELoader加载器
    const rgbeLoader = new RGBELoader();
    // 加载hdr环境图
    rgbeLoader.load("/imgs/fullBG2.hdr", (envTexture) => {
      envTexture.mapping = THREE.EquirectangularReflectionMapping; // 设置映射类型
      scene.background = envTexture; // 设置背景
      scene.environment = envTexture; // 设置环境贴图
    });

    // 21 创建一个平面几何体
    const planeGeometry = new THREE.PlaneGeometry(1, 1.44); // 宽, 高
    // 22 创建一个平面材质
    const planeMaterial = new THREE.MeshBasicMaterial({
      color: 0xffffff, // 图层蒙版: 白色底全部显示, 黑色底全部隐藏
      map: texture, // 23.1.1 将纹理贴到材质上面
      side: THREE.DoubleSide,
      transparent: true, // 23.2 允许透明
      // aoMap: aoMap, // 24.1 将环境遮挡贴图配置到材质上
      // alphaMap: alphaMap, // 25.1 将透明度贴图配置到材质上
      // lightMap: lightMap, // 26.1 光照贴图配置到材质上
    });
    // planeMaterial.map = texture // 23.1.2 将纹理贴到材质上面
    const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);

    scene.add(planeMesh);

    // 24.2 控制面板调试环境遮挡效果强度, 0表示不遮挡
    gui
      .add(planeMaterial, "aoMapIntensity")
      .min(0)
      .max(1)
      .name("环境遮挡效果的强度");
  },
};
</script>

<style>
* {
  margin: 0;
  padding: 0;
}
body {
  height: 100vh;
  width: 100vw;
  overflow: hidden;
}

.full-screen-btn {
  position: fixed;
  left: 2vw;
  top: 2vh;
  z-index: 2;
}
</style>
